<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    什么是继承？
    继承就是可以使得子类具有父类的属性和方法。

    ES5/ES6 的继承除了写法以外还有什么区别？
    class Super {}
    class Sub extends Super {}
    const sub = new Sub();
    Sub.__proto__ === Super;
    子类可以直接通过 __proto__ 寻址到父类。

    function Super() {}
    function Sub() {}
    Sub.prototype = new Super();
    var sub = new Sub();
    Sub.__proto__ === Function.prototype;
    而通过 ES5 的方式，Sub.__proto__ === Function.prototype
    <script>

        /*
            1.原型链继承
            2.借用构造函数继承
            3.组合继承（组合原型链继承和借用构造函数继承）
            4.原型式继承
            5.寄生式继承
            6.寄生组合式继承（常用）
        */

        //1.原型链继承-核心：将父类的实例作为子类的原型
        function Person() {
            this.name = 'zhangsan'
        }
        Person.prototype.sahHi = function () {
            console.log(this.name)
        }
        function Student() {
            this.score = 100
        }
        Student.prototype = new Person()

        //2.借用构造函数继承-在子类的内部调用父类，通过call改变父类中this的指向,等于是复制父类的实例属性给子类
        function Animation() {
            this.name = 'zhangsan'
        }
        Animation.prototype.eat = function () {
            console.log(this.name)
        }
        function Cat() {
            Animation.call(this)
            this.aaa = 1
        }
        let c = new Cat()

        //3.组合继承（组合原型链继承和借用构造函数继承）
        //但是调用了2次父类构造函数
        function ParentType() {
            this.name = 'zhangsan'
        }
        ParentType.prototype.fnc = function () {
            console.log(this.name)
        }
        function SonType() {
            ParentType.call(this)
            this.a = 123
        }
        SonType.prototype = new ParentType()

        let s = new SonType()
        console.log(s)
        //太多了，不想写了

        //其实对于继承的概念，我是这样理解的，
        /*
            子类具有父类的属性和方法，对于实现继承的时候，有一些方法，比如原型链继承，借用构造函数继承，组合继承
            一般情况我们实现一个继承，可能并不想共享父类实例里面的属性和方法，因为父类实例在修改属性的时候会影响到子类
            所以一般可以借用父类构造函数，通过call修改this指向，再将子类的原型指向父类的实例，
            这样子类实例与父类实例都有共有的属性和方法
            而且还可以继承父类原型上的属性和方法

        */
    </script>
</body>

</html>